#ifndef OLED_H
#define OLED_H

#include "oledfont.h"
#include "sysTick.h"
#include <stdio.h>
#include <stm32f4xx.h>
#include <string.h>

// 分辨信息
#define OLED_ROWS 64  // 行数
#define OLED_COLS 128 // 列数

// OLED引脚
#define OLED_PCS GPIO_Pin_10  // CS
#define OLED_PDC GPIO_Pin_12  // DC
#define OLED_PRES GPIO_Pin_11 // RES
#define OLED_PSDA GPIO_Pin_14 // SDA
#define OLED_PSCK GPIO_Pin_13 // SCK

// GPIO
#define OLED_GPIO GPIOB                                                                 // GPIOB组
#define OLED_GPIO_Pin (OLED_PCS | OLED_PSCK | OLED_PSDA | OLED_PRES | OLED_PDC)         // OLED引脚
#define OLED_RCC_AHBPeriphClockCmd RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE) // 时钟使能

// CS
#define OLED_CS_Clr() GPIO_ResetBits(OLED_GPIO, OLED_PCS) // 拉低
#define OLED_CS_Set() GPIO_SetBits(OLED_GPIO, OLED_PCS)   // 拉高

// DC
#define OLED_DC_Clr() GPIO_ResetBits(OLED_GPIO, OLED_PDC) // 拉低
#define OLED_DC_Set() GPIO_SetBits(OLED_GPIO, OLED_PDC)   // 拉高

// RES
#define OLED_RES_Clr() GPIO_ResetBits(OLED_GPIO, OLED_PRES) // 拉低
#define OLED_RES_Set() GPIO_SetBits(OLED_GPIO, OLED_PRES)   // 拉高

// SDA
#define OLED_SDA_Clr() GPIO_ResetBits(OLED_GPIO, OLED_PSDA) // 拉低
#define OLED_SDA_Set() GPIO_SetBits(OLED_GPIO, OLED_PSDA)   // 拉高

// SCK
#define OLED_SCK_Clr() GPIO_ResetBits(OLED_GPIO, OLED_PSCK) // 拉低
#define OLED_SCK_Set() GPIO_SetBits(OLED_GPIO, OLED_PSCK)   // 拉高

/**
 * @name OLED模式
 * @enum
 */
typedef enum tagOLED_MODE {
    OLED_CMD = 0, // CMD
    OLED_DATA = 1 // DATA
} OLED_MODE;

/**
 * @name OLED颜色
 * @enum
 */
typedef enum tagOLED_COLOR {
    OLED_COLOR_BLUE = 0, // 蓝色
    OLED_COLOR_BLACK = 1 // 黑色
} OLED_COLOR;

/**
 * @name OLED旋转
 * @enum
 */
typedef enum tagOLED_ROTATE {
    OLED_ROTATE_0 = 0,  // 0度
    OLED_ROTATE_180 = 1 // 180度
} ROTATE;

/**
 * @name ASCII字体大小
 * @enum
 */
typedef enum tagOLED_ASCIIFONTSIZE {
    OLED_ASCIIFONTSIZE_8_0806 = 8,   // 8号 6*8
    OLED_ASCIIFONTSIZE_12_1206 = 12, // 12号 6*12
    OLED_ASCIIFONTSIZE_16_1608 = 16, // 16号 8*16
    OLED_ASCIIFONTSIZE_24_2412 = 24, // 24号 12*24
} OLED_ASCIIFONTSIZE;

/**
 * @name HZK字体大小
 * @enum
 */
typedef enum tagOLED_HZKFONTSIZE {
    OLED_HZKFONTSIZE_16_1616 = 16, // 16号 16*16
    OLED_HZKFONTSIZE_24_2424 = 24, // 24号 24*24
    OLED_HZKFONTSIZE_32_3232 = 32, // 32号 32*32
    OLED_HZKFONTSIZE_64_6464 = 64, // 64号 64*64
} OLED_HZKFONTSIZE;

/**
 * @name oled初始化
 * @description
 * @function
 * @returns {void}
 * @requires []
 */
void oled_init(void);

/**
 * @name oled设置颜色
 * @description
 * @function
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [color]
 */
void oled_setColor(const OLED_COLOR color);

/**
 * @name oled设置旋转角度
 * @description
 * @function
 * @param {ROTATE} rotate 旋转角度
 * @returns {void}
 * @requires [rotate]
 */
void oled_displayRotate(const ROTATE rotate);

/**
 * @name oled刷新
 * @description
 * @function
 * @returns {void}
 * @requires []
 */
void oled_refresh(void);

/**
 * @name oled清屏
 * @description
 * @function
 * @returns {void}
 * @requires []
 */
void oled_clear(void);

/**
 * @name oled填充
 * @description
 * @function
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [color]
 */
void oled_fill(const OLED_COLOR color);

/**
 * @name 绘制点号
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,color]
 */
void oled_drawPoint(const uint8_t x, const uint8_t y, const OLED_COLOR color);

/**
 * @name 绘制线段
 * @description
 * @function
 * @param {uint8_t} x1 x1坐标
 * @param {uint8_t} y1 y1坐标
 * @param {uint8_t} x2 x2坐标
 * @param {uint8_t} y2 y2坐标
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x1,y1,x2,y2,color]
 */
void oled_drawLine(const uint8_t x1, const uint8_t y1, const uint8_t x2, const uint8_t y2, const OLED_COLOR color);

/**
 * @name 绘制矩形
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {uint8_t} w 宽度
 * @param {uint8_t} h 高度
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,w,h,color]
 */
void oled_drawRect(const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h, const OLED_COLOR color);

/**
 * @name 绘制圆形
 * @description
 * @function
 * @param {uint8_t} x0 x坐标
 * @param {uint8_t} y0 y坐标
 * @param {uint8_t} r 半径
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,r,color]
 */
void oled_drawCircle(const uint8_t x0, const uint8_t y0, const uint8_t r, const OLED_COLOR color);

/**
 * @name 绘制字符
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {uint8_t} ch 字符
 * @param {OLED_ASCIIFONTSIZE} size 大小
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,ch,size,color]
 */
void oled_showASCII(uint8_t x, uint8_t y, const uint8_t ch, const OLED_ASCIIFONTSIZE size, const OLED_COLOR color);

/**
 * @name 绘制汉字
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {uint8_t} index 汉字索引
 * @param {OLED_HZKFONTSIZE} size 大小
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,index,size,color]
 */
void oled_showHZK(uint8_t x, uint8_t y, const uint8_t index, const OLED_HZKFONTSIZE size, const OLED_COLOR color);

/**
 * @name 绘制数字
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {double} number 数字
 * @param {uint8_t} digit 位数
 * @param {OLED_ASCIIFONTSIZE} size 大小
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,number,digit,size,color]
 */
void oled_showNumber(uint8_t x, uint8_t y, const double number, const uint8_t digit, const OLED_ASCIIFONTSIZE size, const OLED_COLOR color);

/**
 * @name 绘制ASCII字符串
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {uint8_t} *str ASCII字符串
 * @param {OLED_ASCIIFONTSIZE} size 大小
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,str,size,color]
 */
void oled_showASCIIString(uint8_t x, uint8_t y, const uint8_t *str, const OLED_ASCIIFONTSIZE size, const OLED_COLOR color);

/**
 * @name 绘制HZK字符串
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {int32_t} *str HZK字符串(索引列表; -1结束)
 * @param {OLED_HZKFONTSIZE} size 大小
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,str,size,color]
 */
void oled_showHZKString(uint8_t x, uint8_t y, const int32_t *str, const OLED_HZKFONTSIZE size, const OLED_COLOR color);

/**
 * @name 绘制图片
 * @description
 * @function
 * @param {uint8_t} x x坐标
 * @param {uint8_t} y y坐标
 * @param {uint8_t} width 宽度
 * @param {uint8_t} height 高度
 * @param {uint8_t} *bmp 图片
 * @param {OLED_COLOR} color 颜色
 * @returns {void}
 * @requires [x,y,width,height,bmp,color]
 */
void oled_showPicture(uint8_t x, uint8_t y, uint8_t width, uint8_t height, const uint8_t *bmp, const OLED_COLOR color);
#endif
